package optional;

import java.io.LineNumberReader;
import java.util.Optional;

import org.apache.commons.lang3.StringUtils;
import org.apache.poi.util.StringUtil;
import org.testng.annotations.Test;
import util.MathUtil;

/**
 *
 * 1.消除if判断
 *
 *
 *
 *
 *
 *
 * orElse和orElseGet的区别：
 * 最关键的区别就是，前者立即计算，后者是延迟计算。所以如果备选值是无需计算的，现在已有的，那就用orElse。
 * 如果值还没得到，那最好用orElseGet延迟执行。一般最多的情况是类似字符串拼装、创建新对象这样的，都应该用orElseGet。
 * 说白了就是传值就用orElse，需要调用方法获取就用orElseGet。
 * 就怕不了解的人在orElse中传入了方法，而且方法中含有更新修改类的操作。这样就不光是CPU或者耗时的问题了。
 *
 *
 *
 */
public class OptionalBase {



    public static void main(String[] args) {
        base();
    }

    public static void base() {
        Optional<Object> empty = Optional.empty();
        System.out.println(empty);
    }

    public String getStringRandom() {
        if (Math.random() > 0.5) {
            return "OK";
        } else {
            return null;
        }

    }

    @Test
    public void get () {
        String str1 = null;
        String str2 = "A";
        String str3 = getStringRandom();
        System.out.println("str3 :" + str3);

        // 报错NPE
//        String s1 = Optional.of(str1).orElse("a");

        // orElse()无论如何都会执行括号中的内容，orElseGet()只在主体 value 是空时执行
        String s2 = Optional.of(str2).orElseGet(() -> "b");
        String s22 = Optional.of(str2).orElseGet(() -> str2);

        String str31 = Optional.of(str3).orElseGet(() -> "b");
        String str32 = Optional.of(str3).orElseGet(() -> str2);

        System.out.println(s2);
        System.out.println(s22);


        String s3 = Optional.ofNullable(str1).orElse("a");
        String s4 = Optional.ofNullable(str2).orElse("s4");


    }

    @Test(invocationCount = 6)
    public void getElse() {
        String str = null;
        String str3 = getStringRandom();
        System.out.println("str3 :" + str3);
        // 使用Optional的时候带上泛型
        Optional<String> optional = Optional.ofNullable(str3);
        String s = optional.orElseGet(() -> str);

        // orElseGet：optional和supplier都为null时会发生NEP
//        String s1 = optional.orElseGet(null);

        // orElse：optional和supplier都为null也不会发生NEP
//        String s11 = optional.orElse(null);

//        System.out.println(s1);
//        System.out.println(s11);

        String s2 = optional.orElse("orElse");
        System.out.println(s);
        System.out.println(s2);

    }

    @Test
    public void testThrow() {
        String str1 = null;
        String str2 = "A";

        Optional.ofNullable(str1).orElseThrow();
        Optional.ofNullable(str2).orElseThrow();
    }

    public String getDefault() {
        String s = "do invoke";
        System.out.print(s);
        return s;
    }

    @Test(invocationCount = 1)
    public void getAndGetOrElse() {

        /**
         * orElse的【参数】必然会执行
         */

        //output: do invoke,所以即使optional有值，也会执行
        Optional.of("string").orElse(getDefault());
        Optional.empty().orElse(getDefault());
        //output:
        String name2 = Optional.of("string").orElseGet(this::getDefault);
    }

    @Test(invocationCount = 5, description = "消除if判断")
    public void ifCase() {
        String s = Math.random() > 0.5 ? "a" : null;
        var res = Optional.ofNullable(s)
                .map(String::toUpperCase)
                .orElse("default");

        System.out.println(res);
    }

    @Test(invocationCount = 3)
    public void ifCase2() {
        String s = Math.random() > 0.5 ? "OK" : null;

//        s = Optional.ofNullable(s).orElse("OKK");
        Optional.ofNullable(s).filter(StringUtils::isEmpty).map(str -> "");

        System.out.println(s);

        String b = null;
        System.out.println("b : " + b);

    }

    /**
     * isEmpty方法
     */
    @Test
    public void testEmpty() {
        var op = Optional.ofNullable(null);


    }


}
